# -*- coding:utf-8 -*-
from api_doc import ApiDoc
from tkinter import *
from flask import *
import os
import json
import tkinter as tk  # 使用Tkinter前需要先导入
import tkinter.font as tf
import threading
import tkinter.messagebox
import logging
import random
import requests
from flask_cors import *
from linksql import *

app = Flask(__name__)
app.config.from_object(__name__)

# # 接口文档样式
# # 需要显示文档的 Api

app.config['API_DOC_MEMBER'] = ['api']
# 需要排除的 RESTful Api 文档
# app.config['RESTFUL_API_DOC_EXCLUDE'] = []
api = Blueprint('api', __name__)
ApiDoc(app)

CORS(app, resources=r'/*')


# 禁用控制台
log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)


def GetNameByEveryDir(file_dir, videoProperty):
    # Input   Root Dir and get all img in per Dir.
    # Out     Every img with its filename and its dir and its path
    FileNameWithPath = []
    FileName = []
    FileDir = []
    for root, dirs, files in os.walk(file_dir):
        for file in files:
            if os.path.splitext(file)[1] in videoProperty:
                FileNameWithPath.append(os.path.join(root, file))  # 保存图片路径
                FileName.append(file)                             # 保存图片名称
                FileDir.append(root[len(file_dir):])            # 保存图片所在文件夹
    return FileName, FileNameWithPath, FileDir

# 接口返回样式


def response_return(code, msg, data):
    """[summary]
    Args:
        code ([type]): 200(请求成功),404(请求失败),500(服务器出错)
        msg ([type]): msg
        data ([type]): json_data
    Returns:
        [type]: [description]
    """
    if data == None:
        data = []
    return json.dumps({'code': code, 'msg': msg, 'data': list(data)}, ensure_ascii=False)

# 错误日志写入


def write_error(e):
    """[summary]
    Args:
        e ([type]): [description]
    """
    # 打开文件，没有就自动创建
    with open('error.txt', 'a') as file_handle:
        file_handle.write("error: %s--%s" %
                          (e.__traceback__.tb_lineno, str(e)))  # 写入
        file_handle.write('\n')

# 登录路由


@api.route('/login', methods=['post'])
def login():
    """
    登录接口，接受两个jsong格式参数，跟数据库匹对，匹对成功返回用户信息！返回格式为json数据！
    @@@
    #### args

    | args | nullable | type | remark |
    |--------|--------|--------|--------|
    |    phone_number    |    false    |    string   |    手机号    |
    |    password    |    false    |    string   |    用户密码    |

    #### methods
    > post
    #### return
    - ##### json-success
    > {"code": "200", "msg": "success", "data": [{"username": "似水流年", "phone_number": "18818888866"}]}
    - ##### json-fail
    > {"code": "404", "msg": "Unknown user", "data": []}
    @@@
    """
    try:
        # 获取前端发送的json数据
        post_data = request.data.decode('utf-8')
        # 获取到POST过来的数据，因为我这里传过来的数据需要转换一下编码。根据具体情况而定
        data_json = json.loads(post_data)
        # 提取数据
        phone_number = data_json['phone_number']
        password = data_json['password']
        # 与sqlit3 数据库匹对
        res = user_showdb(phone_number, password)
        # 如返回不为空，说明有注册信息，可以登陆
        if res:
            data_dict = {"username": res[0], "phone_number": res[1]}
            res = []
            res.append(data_dict)
            return response_return('200', 'success', res)
        else:
            return response_return('404', 'Unknown user', None)
    except Exception as e:
        write_error(e)
        return response_return('500', 'Unknown server error', None)

# 注册路由


@api.route('/register', methods=['post'])
def register():
    """
    注册接口，接受三个jsong格式参数，插入数据库，返回是否插入成功！返回格式为json数据！
    @@@
    #### args

    | args | nullable | type | remark |
    |--------|--------|--------|--------|
    |    username    |    false    |    string   |    用户昵称    |
    |    phone_number    |    false    |    string   |    手机号    |
    |    password    |    false    |    string   |    用户密码    |

    #### methods
    > post
    #### return
    - ##### json-success
    > {"code": "200", "msg": "success", "data": []}
    - ##### json-fail
    > {"code": "500", "msg": "InsertData fail", "data": []}
    @@@
    """
    try:
        post_data = request.data.decode('utf-8')
        # 获取到POST过来的数据，因为我这里传过来的数据需要转换一下编码。根据具体情况而定
        data_json = json.loads(post_data)
        username = data_json['username']
        phone_number = data_json['phone_number']
        password = data_json['password']
        # 注册信息直接插入数据库
        user_InsertData(username, phone_number, password)
        return response_return('200', 'success', None)
    except Exception as e:
        write_error(e)
        return response_return('500', 'Unknown server error', None)

# 登录路由


@api.route('/alter', methods=['post'])
def alter():
    """
    修改用户昵称接口，接受两个jsong格式参数，跟数据库匹对，匹对成功修改用户信息！
    @@@
    #### args

    | args | nullable | type | remark |
    |--------|--------|--------|--------|
    |    phone_number    |    false    |    string   |    手机号    |
    |    username    |    false    |    string   |    用户昵称   |

    #### methods
    > post
    #### return
    - ##### json-success
    > {"code": "200", "msg": "success", "data": []}
    - ##### json-fail
    > {"code": "404", "msg": "Unknown user", "data": []}
    @@@
    """
    try:
        # 获取前端发送的json数据
        post_data = request.data.decode('utf-8')
        # 获取到POST过来的数据，因为我这里传过来的数据需要转换一下编码。根据具体情况而定
        data_json = json.loads(post_data)
        # 提取数据
        phone_number = data_json['phone_number']
        username = data_json['username']
        # 与sqlit3 数据库匹对
        res = user_alter(username, phone_number)
        # 如返回不为空，说明有注册信息，可以登陆
        if res:
            return response_return('200', 'success', None)
        else:
            return response_return('404', 'Unknown user', None)
    except Exception as e:
        write_error(e)
        return response_return('500', 'Unknown server error', None)

# 登录路由


@api.route('/delete', methods=['post'])
def delete():
    """
    删除用户接口，接受一个jsong格式参数，跟数据库匹对，匹对成功删除用户信息！
    @@@
    #### args

    | args | nullable | type | remark |
    |--------|--------|--------|--------|
    |    phone_number    |    false    |    string   |    手机号    |

    #### methods
    > post
    #### return
    - ##### json-success
    > {"code": "200", "msg": "success", "data": []}
    - ##### json-fail
    > {"code": "404", "msg": "Unknown user", "data": []}
    @@@
    """
    try:
        # 获取前端发送的json数据
        post_data = request.data.decode('utf-8')
        # 获取到POST过来的数据，因为我这里传过来的数据需要转换一下编码。根据具体情况而定
        data_json = json.loads(post_data)
        # 提取数据
        phone_number = data_json['phone_number']
        # 与sqlit3 数据库匹对
        res = user_deldb(phone_number)
        # 如返回不为空，说明有注册信息，可以登陆
        if res:
            return response_return('200', 'success', None)
        else:
            return response_return('404', 'Unknown user', None)
    except Exception as e:
        write_error(e)
        return response_return('500', 'Unknown server error', None)


@api.route('/getYingyu', methods=['GET', 'POST'])
def getYingyu():
    """
    随机英语加译文
    @@@
    #### args

    | args | nullable | type | remark |
    |--------|--------|--------|--------|
    |    size    |    false    |    int   |    返回数量    |

    #### methods
    > post,get
    #### return
    - ##### json-success
    > {"code": "200", "msg": "success", "data": [["Never believe that a few caring people can't change the world. For, indeed, that's all who ever have.", "永远不要怀疑一小部分热心的民众能够改变世界。事实上，他们是唯一曾改变世界的人。"], ["The lives of the dead are recorded in the minds of the living.", "生者记忆中，逝者长存。"], ["I don’t think that anybody can grow unless he really is accepted exactly as he is.", "一个人除非真正接受自己，否则他没法成长。"]]}
    - ##### json-fail
    > {"code": "404", "msg": "Unknown user", "data": []}
    @@@
    """
    try:
        post_data = request.data.decode('utf-8')
        # 获取到POST过来的数据，因为我这里传过来的数据需要转换一下编码。根据具体情况而定
        data_json = json.loads(post_data)
        size = data_json['size']
        all_data = []
        for i in range(0, int(size)):
            Y = '2020'
            m = random.randint(1, 12)
            if m < 10:
                M = '0' + str(m)
            else:
                M = str(m)
            d = random.randint(1, 28)
            if d < 10:
                D = '0' + str(d)
            else:
                D = str(d)
            url = 'http://sentence.iciba.com/index.php?c=dailysentence&m=getdetail&title=' + \
                Y + "-" + M + "-" + D
            r = requests.post(url)
            a = r.json()
            all_data.append([a['content'], a['note']])
        try:
            return response_return('200', 'success', all_data)
        except:
            return response_return('200', 'success', ['This bowl is spilled, another bowl!', '这碗洒了，再来一碗！'])
    except Exception as e:
        write_error(e)
        return response_return('500', 'Unknown server error', None)


@api.route('/getMp3', methods=['GET', 'POST'])
def getMp3():
    """
    随机英语Mp3
    @@@
    #### args

    | args | nullable | type | remark |
    |--------|--------|--------|--------|
    |    size    |    false    |    int   |    返回数量    |

    #### methods
    > post,get
    #### return
    - ##### json-success
    > {"code": "200", "msg": "success", "data": [[{"id": 3969, "content": "A minute on the lips, a lifetime on the hips.", "source": "新版每日一句", "note": "嘴上一时享受，臀上一世肥肉。", "tts": "https://staticedu-wps.cache.iciba.com/audio/e50ca16b39ef22b605565ad2b749ce8e.mp3", "imgurl": "https://staticedu-wps.cache.iciba.com/image/dcd433a0ad0bdd60d84b9c73b8f21904.png", "date": "2020-12-07"}], [{"id": 3828, "content": "Having dreams is what makes life tolerable.", "source":
"新版每日一句", "note": "梦想使生活得以忍受。", "tts": "https://edu-wps.ks3-cn-beijing.ksyun.com/audio/1e7b2ff7ea053dd3ea574d1f5fea3d10.mp3", "imgurl": "https://edu-wps.ks3-cn-beijing.ksyun.com/image/cc5c924d9356dacde45c4db2b5d4842c.png", "date": "2020-07-19"}]]}
    - ##### json-fail
    > {"code": "404", "msg": "Unknown user", "data": []}
    @@@
    """
    try:
        post_data = request.data.decode('utf-8')
        # 获取到POST过来的数据，因为我这里传过来的数据需要转换一下编码。根据具体情况而定
        data_json = json.loads(post_data)
        size = data_json['size']
        all_data = []
        for i in range(0, int(size)):
            Y = '2020'
            m = random.randint(1, 12)
            if m < 10:
                M = '0' + str(m)
            else:
                M = str(m)
            d = random.randint(1, 28)
            if d < 10:
                D = '0' + str(d)
            else:
                D = str(d)
            APIKEY = "45f109b9d583b7051315b33294169819"
            date = '%s-%s-%s' % (Y, M, D)
            url = 'http://api.tianapi.com/txapi/everyday/index?key=%s&date=%s' % (
                APIKEY, date)
            response = requests.get(url)
            response.enconding = "utf-8"
            data = json.loads(response.text)
            all_data.append(data['newslist'][0])
        return response_return('200', 'success', all_data)
    except Exception as e:
        write_error(e)
        return response_return('500', 'Unknown server error', None)


@api.route('/getMp4', methods=['GET', 'POST'])
def getMp4():
    """
    随机英语Mp4
    @@@
    #### args

    | args | nullable | type | remark |
    |--------|--------|--------|--------|
    |    size    |    false    |    int   |    返回数量    |

    #### methods
    > post,get
    #### return
    - ##### json-success
    >{"code": "200", "msg": "success", "data": [{"video_url": "http://127.0.0.1:5000/static/video/1 - 副本 - 副本.mp4"}, {"video_url": "http://127.0.0.1:5000/static/video/1 - 副本.mp4"}, {"video_url": "http://127.0.0.1:5000/static/video/1.mp4"}]}
    - ##### json-fail
    > {"code": "404", "msg": "Unknown user", "data": []}
    @@@
    """
    try:
        post_data = request.data.decode('utf-8')
        # 获取到POST过来的数据，因为我这里传过来的数据需要转换一下编码。根据具体情况而定
        data_json = json.loads(post_data)
        size = data_json['size']
        all_data = []
       # 获取static\\video\\路径下的所有mp4文件，包括名称，路径，文件夹名称
        FileName, FileNameWithPath, FileDir = GetNameByEveryDir(
            './static/video/', '.mp4')
        if int(size) > len(FileName):
            for i in FileName:
                a = {}
                url = 'http://10.0.2.2:5000/static/video/%s' % (i)
                a['video_url'] = url
                all_data.append(a)
        else:
            for i in range(0, int(size)):
                a = {}
                url = 'http://10.0.2.2:5000/static/video/%s' % (
                    FileName[random.randint(0, len(FileName))])
                a['video_url'] = url
                all_data.append(a)
        return response_return('200', 'success', all_data)
    except Exception as e:
        write_error(e)
        return response_return('500', 'Unknown server error', None)


@api.route('/getWords', methods=['GET', 'POST'])
def getWords():
    """
    返回20个小学英语单词意思，带mp3
    @@@
    #### methods
    > post,get
    #### return
    - ##### json-success
    >{"code": "200", "msg": "success", "data": [{"symbol": "[ˈhɔrə]", "sound": "https://v.ylapi.cn/img/api/api_reciteword_word_list/2af80c5e3404bb1c.mp3", "class_id": "24420", "name": "horror", "course": "14", "class_title": "高三 下学期", "desc": "n. 恐怖; 憎恶"}]}
    - ##### json-fail
    > {"code": "500", "msg": "Unknown server error", "data": []}
    @@@
    """
    try:
        class_id = [
            {'class_id': '5544', 'word_num': '21',
                'title': 'Student Book 1', 'course_num': '2'},
            {'class_id': '11130', 'word_num': '42',
                'title': 'Student Book 2', 'course_num': '3'},
            {'class_id': '2926', 'word_num': '11',
                'title': 'Student Book 3', 'course_num': '1'},
            {'class_id': '7476', 'word_num': '28',
                'title': 'Student Book 4', 'course_num': '2'},
            {'class_id': '4020', 'word_num': '15',
                'title': 'Student Book 5', 'course_num': '1'},
            {'class_id': '5380', 'word_num': '20',
                'title': 'Student Book 6', 'course_num': '1'},
            {'class_id': '8910', 'word_num': '33',
                'title': 'Student Book 7', 'course_num': '2'},
            {'class_id': '11111', 'word_num': '41',
                'title': 'Student Book 8', 'course_num': '3'},
            {'class_id': '99408', 'word_num': '152',
                'title': '第一册', 'course_num': '8'},
            {'class_id': '93010', 'word_num': '142',
                'title': '第二册', 'course_num': '8'},
            {'class_id': '24272', 'word_num': '37',
                'title': '第三册', 'course_num': '2'},
            {'class_id': '32193', 'word_num': '49',
                'title': '第四册', 'course_num': '3'},
            {'class_id': '7548', 'word_num': '51',
                'title': '第五册', 'course_num': '3'},
            {'class_id': '9387', 'word_num': '63',
                'title': '第六册', 'course_num': '4'},
            {'class_id': '8400', 'word_num': '56',
                'title': '第七册', 'course_num': '3'},
            {'class_id': '11627', 'word_num': '77',
                'title': '第八册', 'course_num': '4'},
            {'class_id': '15912', 'word_num': '104',
                'title': '第九册', 'course_num': '6'},
            {'class_id': '23716', 'word_num': '154',
                'title': '第十册', 'course_num': '8'},
            {'class_id': '22010', 'word_num': '142',
                'title': '第十一册', 'course_num': '8'},
            {'class_id': '5146', 'word_num': '83',
                'title': '一年级 上学期', 'course_num': '5'},
            {'class_id': '3213', 'word_num': '51',
                'title': '一年级 下学期', 'course_num': '3'},
            {'class_id': '3264', 'word_num': '51',
                'title': '二年级 上学期', 'course_num': '3'},
            {'class_id': '3835', 'word_num': '59',
                'title': '二年级 下学期', 'course_num': '3'},
            {'class_id': '4950', 'word_num': '75',
                'title': '三年级 上学期', 'course_num': '4'},
            {'class_id': '4623', 'word_num': '69',
                'title': '三年级 下学期', 'course_num': '4'},
            {'class_id': '4624', 'word_num': '68',
                'title': '四年级 上学期', 'course_num': '4'},
            {'class_id': '6693', 'word_num': '97',
                'title': '四年级 下学期', 'course_num': '5'},
            {'class_id': '5810', 'word_num': '83',
                'title': '五年级 上学期', 'course_num': '5'},
            {'class_id': '5183', 'word_num': '73',
                'title': '五年级 下学期', 'course_num': '4'},
            {'class_id': '19800', 'word_num': '275',
                'title': '六年级 上学期', 'course_num': '14'},
            {'class_id': '13286', 'word_num': '182',
                'title': '六年级 下学期', 'course_num': '10'}
        ]
        chiose = class_id[random.randint(0, len(class_id)-1)]
        url = "http://rw.ylapi.cn/reciteword/wordlist.u?uid=11551&appkey=111a8e9c15660760a272ca26335b5b35&class_id=%s&course=%s" % (
            chiose['class_id'], random.randint(1, int(chiose['course_num'])))
        response = requests.post(url)
        response.enconding = "utf-8"
        result_data = json.loads(response.text)
        all_data = result_data['datas']
        return response_return('200', 'success', all_data)
    except Exception as e:
        write_error(e)
        return response_return('500', 'Unknown server error', None)

@api.route('/getWordsHight', methods=['GET', 'POST'])
def getWordsHight():
    """
    返回20个中学英语单词意思，带mp3
    @@@
    #### methods
    > post,get
    #### return
    - ##### json-success
    >{"code": "200", "msg": "success", "data": [{"symbol": "[ˈhɔrə]", "sound": "https://v.ylapi.cn/img/api/api_reciteword_word_list/2af80c5e3404bb1c.mp3", "class_id": "24420", "name": "horror", "course": "14", "class_title": "高三 下学期", "desc": "n. 恐怖; 憎恶"}]}
    - ##### json-fail
    > {"code": "500", "msg": "Unknown server error", "data": []}
    @@@
    """
    try:
        class_id = [
                    {"class_id": "30302", "word_num": "278", "title": "必修1", "course_num": "14"},
        {"class_id": "29150", "word_num": "265", "title": "必修2", "course_num": "14"},
        {"class_id": "40182", "word_num": "362", "title": "必修3", "course_num": "19"},
        {"class_id": "33488", "word_num": "299", "title": "必修4", "course_num": "15"}, 
        {"class_id": "38872", "word_num": "344", "title": "必修5", "course_num": "18"},
        {"class_id": "45045", "word_num": "385", "title": "选修6", "course_num": "20"}, 
        {"class_id": "44722", "word_num": "379", "title": "选修7", "course_num": "19"},
        {"class_id": "18650", "word_num": "373", "title": "高一 上学期", "course_num": "19"},
        {"class_id": "25143", "word_num": "493", "title": "高一 下学期", "course_num": "25"}, 
        {"class_id": "24388", "word_num": "469", "title": "高二 上学期", "course_num": "24"}, 
        {"class_id": "21094", "word_num": "398", "title": "高二 下学期", "course_num": "20"},
        {"class_id": "26460", "word_num": "490", "title": "高三 上学期", "course_num": "25"}, 
        {"class_id": "24420", "word_num": "444", "title": "高三 下学期", "course_num": "23"}
        ]
        chiose = class_id[random.randint(0, len(class_id)-1)]
        url = "http://rw.ylapi.cn/reciteword/wordlist.u?uid=11551&appkey=111a8e9c15660760a272ca26335b5b35&class_id=%s&course=%s" % (
            chiose['class_id'], random.randint(1, int(chiose['course_num'])))
        response = requests.post(url)
        response.enconding = "utf-8"
        result_data = json.loads(response.text)
        all_data = result_data['datas']
        return response_return('200', 'success', all_data)
    except Exception as e:
        write_error(e)
        return response_return('500', 'Unknown server error', None)

# 服务器启动
def run_sever():
    app.register_blueprint(api, url_prefix='/api')
    app.run(host='0.0.0.0', port=5000, debug=False, use_reloader=False)

# 打开服务器按钮调用事件


def start():
    global l, chiose
    if chiose == 0:
        thre = threading.Thread(target=run_sever)   # 创建一个线程运行服务器
        thre.setDaemon(True)
        thre.start()  # 运行线程
        chiose = 1
        l["text"] = "接口地址\n鼠标左键点开查看：\nhttp://127.0.0.1:5000/docs/api/"
        tkinter.messagebox.showinfo('成功', '已开启服务！')
    else:
        tkinter.messagebox.showinfo('提示', '服务已运行！')


def about():
    tkinter.messagebox.showinfo('帮助', '后台接口')


def connect():
    import webbrowser
    webbrowser.open("http://127.0.0.1:5000/docs/api/")


def open_api_doc(event):
    import webbrowser
    webbrowser.open("http://127.0.0.1:5000/docs/api/")


if __name__ == '__main__':
    root = Tk()
    # 设置窗口大小
    winWidth = 600
    winHeight = 400
    # 获取屏幕分辨率
    screenWidth = root.winfo_screenwidth()
    screenHeight = root.winfo_screenheight()
    x = int((screenWidth - winWidth) / 2)
    y = int((screenHeight - winHeight) / 2)
    # 设置主窗口标题
    root.title("后台接口")
    # 设置窗口初始位置在屏幕居中
    root.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x, y))
    # 设置窗口图标
    root.iconbitmap("./img/cxk.ico")
    # 设置窗口宽高固定
    root.resizable(0, 0)
    # 添加菜单栏
    f = tkinter.Menu(root)
    root['menu'] = f
    f.add_command(label='关于', command=about)
    f.add_command(label='联系作者', command=connect)
    # 增加背景图片
    photo = tk.PhotoImage(file="./img/no_bg.png")
    theLabel = tk.Label(root, text="", justify=tk.LEFT,
                        image=photo, compound=tk.CENTER)
    theLabel.place(relx=0.8, rely=0.63, anchor=CENTER)
    chiose = 0
    Button(root, text='开启服务', command=start).place(
        relx=0.8, rely=0.08, anchor=CENTER)
    Button(root, text='更换网址', command="#").place(
        relx=0.7, rely=0.2, anchor=CENTER)
    Button(root, text='文件所在', command="#").place(
        relx=0.9, rely=0.2, anchor=CENTER)
    ft = tf.Font(family='微软雅黑', size=15)
    l = Label(root, font=ft)
    l.bind("<Button-1>", open_api_doc)
    l.place(relx=0.3, rely=0.5, anchor=CENTER)
    root.mainloop()
